#include "glMesh.h"

// --------------------------------------------------------
// Ctor
// --------------------------------------------------------
CglMesh::CglMesh()
{
	Null();
}

CglMesh::~CglMesh()
{
	Release();
}

CglMesh::CglMesh(const CXobjIO & xobjIO)
{
	Create(xobjIO);
}

void CglMesh::Create(const CXobjIO & x)
{
	matrixWS = x.matrixWS;
	//material = x.material;

	uint8 createFlags = BUFFER_H_AND_B;

	if (x.pos.size() > 0)
	{
		uint32 vertexCount = (uint32) x.pos.size();

		pos.Create(vertexCount, createFlags, true);

		memcpy( (void *)    pos[BUFFER_R], 
			      (void *) &x.pos[0], 
			      vertexCount * sizeof( x.pos[0] ));
	}

	if (x.nml.size() > 0)
	{
		uint32 normalCount = (uint32) x.nml.size();

		nml.Create(normalCount, createFlags, true);

		memcpy( (void *)    nml[BUFFER_R], 
			      (void *) &x.nml[0], 
			      normalCount * sizeof( x.nml[0] ));
	}

	if (x.tnt.size() > 0)
	{
		uint32 tangentCount = (uint32) x.tnt.size();

		tnt.Create(tangentCount, createFlags, true);

		memcpy( (void *)    tnt[BUFFER_R], 
			      (void *) &x.tnt[0], 
			      tangentCount * sizeof( x.tnt[0] ));
	}

	if (x.bnt.size() > 0)
	{
		uint32 bitangentCount = (uint32) x.bnt.size();

		bnt.Create(bitangentCount, createFlags, true);

		memcpy( (void *)    bnt[BUFFER_R], 
			      (void *) &x.bnt[0], 
			      bitangentCount * sizeof( x.bnt[0] ));
	}

	if (x.clr.size() > 0)
	{
		uint32 colorCount = (uint32) x.clr.size();

		clr.Create(colorCount, createFlags, false);

		memcpy( (void *)    clr[BUFFER_R], 
			      (void *) &x.clr[0], 
			      colorCount * sizeof( x.clr[0] ));
	}

	if (x.uv.size() > 0)
	{
		uint32 uvCount = (uint32) x.uv.size();

		uv.Create(uvCount, createFlags, false);

		memcpy( (void *)    uv[BUFFER_R], 
			      (void *) &x.uv[0], 
			      uvCount * sizeof( x.uv[0] ));
	}

	if (x.posIdx.size() > 0)
	{
		uint32 indexCount = (uint32) x.posIdx.size();

		posIdx.Create(indexCount, createFlags, false);

		memcpy( (void *)    posIdx[BUFFER_R], 
			      (void *) &x.posIdx[0], 
			      indexCount * sizeof( x.posIdx[0] ));
	}

	if (x.uvIdx.size() > 0)
	{
		uint32 uvIndexCount = (uint32) x.uvIdx.size();

		uvIdx.Create(uvIndexCount, createFlags, false);

		memcpy( (void *)    uvIdx[BUFFER_R], 
			      (void *) &x.uvIdx[0], 
			      uvIndexCount * sizeof( x.uvIdx[0] ));
	}

	if (x.clrIdx.size() > 0)
	{
		uint32 colorIndexCount = (uint32) x.clrIdx.size();

		clrIdx.Create(colorIndexCount, createFlags, false);

		memcpy( (void *)    clrIdx[BUFFER_R], 
			      (void *) &x.clrIdx[0], 
			      colorIndexCount * sizeof( x.clrIdx[0] ));
	}

	Update(BUFFER_R);

	program = NULL;
}

void CglMesh::Null()
{
	memset( (void *) &matrixWS, 0, sizeof(matrixWS));
	memset( (void *) &material, 0, sizeof(material));

	program = NULL;
}

void CglMesh::Update(uint8 uFlags)
{
  pos.Update( uFlags );
  nml.Update( uFlags );
  tnt.Update( uFlags );
  bnt.Update( uFlags );
  clr.Update( uFlags );
  uv.Update ( uFlags );
  
  posIdx.Update( uFlags );
  clrIdx.Update( uFlags );
	uvIdx.Update ( uFlags );
}

void CglMesh::Release()
{
	uint8 rFlags = BUFFER_H | BUFFER_B;

  pos.Release(rFlags);
  nml.Release(rFlags);
  tnt.Release(rFlags);
  bnt.Release(rFlags);
  clr.Release(rFlags);
  uv.Release (rFlags);

  posIdx.Release(rFlags);
  clrIdx.Release(rFlags);
  uvIdx.Release (rFlags);
}

void CglMesh::Swap()
{
	pos.Swap();
	nml.Swap();
	tnt.Swap();
	bnt.Swap();
}